package com.yeskery.nut.websocket;

import com.yeskery.nut.bean.ApplicationContext;
import com.yeskery.nut.bean.BeanFactoryPriorityPostProcessor;
import com.yeskery.nut.bean.FactoryBeanRegister;
import com.yeskery.nut.core.SuspendException;
import com.yeskery.nut.util.ReflectUtils;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * WebSocket的BeanFactory后置处理器
 * @author sprout
 * @version 1.0
 * 2023-04-15 23:06
 */
public class WebSocketBeanFactoryPriorityPostProcessor implements BeanFactoryPriorityPostProcessor {

    /** 请求路径缓存集合 */
    private final Set<String> pathCacheSet = new HashSet<>();

    @Override
    public void process(ApplicationContext applicationContext) throws Exception {
        Collection<WebSocketConfiguration> webSocketConfigurations = applicationContext.getBeans(WebSocketConfiguration.class);
        Collection<WebSocketConfigurationCollector> webSocketConfigurationCollectors = applicationContext.getBeans(WebSocketConfigurationCollector.class);
        for (WebSocketConfigurationCollector webSocketConfigurationCollector : webSocketConfigurationCollectors) {
            webSocketConfigurations.addAll(webSocketConfigurationCollector.getWebSocketConfigurations());
        }

        for (WebSocketConfiguration webSocketConfiguration : webSocketConfigurations) {
            String basePath = webSocketConfiguration.getWebSocketServerConfigure().getPathMetadata().getBasePath();
            if (pathCacheSet.contains(basePath)) {
                throw new SuspendException("WebSocket Server Endpoint[" + basePath + "] Already Registered.");
            }
            pathCacheSet.add(basePath);
        }

        WebSocketRegisterFactory webSocketRegisterFactory = new DefaultWebSocketRegisterFactory();
        webSocketRegisterFactory.registerAll(webSocketConfigurations);
        ((FactoryBeanRegister) applicationContext).registerBean(ReflectUtils.getDefaultBeanName(WebSocketRegisterFactory.class),
                webSocketRegisterFactory, WebSocketRegisterFactory.class);
    }
}
